/*
 * 文件作用：实现音频解码、控制、播放的头文件
 * 文件描述：声明类：
 *          类musicHangdle：音频的解码与播放控制
 *          类msuicProcessThread：音频解码线程
 *          类musicPlayThread：音频播放线程
 * 文件创建时间：2017-5-2
 * 文件创建者：wsgalaxy<wsgalaxy@163.com>
 * 文件最后修改时间：
 * 文件修改者：
 * 文件协议：GPL
 *
 */



#ifndef MUSICHANDLE_H
#define MUSICHANDLE_H

#include <QObject>
#include <QAudioOutput>
#include <QThread>

#include "musicId3v2Info.h"
#include "globalValue.h"


class musicProcessThread;
class musicPlayThread;

/*
 * @描述 音乐播放解码控制类
 */
class musicHandle : public QObject
{
    Q_OBJECT
public:
    char isMusicSeted;              //音乐是否被设置
    char isMusicProcessed;          //音乐是否解码完毕
    char *musicName;                //音乐名
    musicId3v2Info info;            //音乐信息
    uint32_t pcmSize;               //解码后文件体积
    char *pcmData;                  //解码后文件数据

    double volume;                  //音量
    uint32_t sumTimeSec;            //音频时间
    uint32_t currentTimeSec;        //当前时间
    uint32_t startTimeSec;          //音乐播放开始时间
    QAudioOutput *pcmOutput;        //音频输出
    QIODevice *pcmDevice;           //输出设备

    QThread *playThread;            //音频播放线程
    QThread *processThread;         //音频解码线程

    musicPlayThread *musicPlayDowork;           //播放音频线程执行类
    musicProcessThread *musicProcessDowork;     //解码音频线程执行类

    int state;                      //状态 0:play 1:pause 2:destroy

    explicit musicHandle(QObject *parent = 0);
    ~musicHandle();

    /*
     * @描述 设置音乐
     * @参数 url 音频文件路径
     * @返回 0成功，否则失败
     */
    int setMusic(char* url);

    /*
     * @描述 开启音乐播放线程
     * @返回 0成功，否则失败
     */
    int musicPlayThreadStart();

    /*
     * @描述 解码音频文件
     * @返回 0成功，否则失败
     */
    int musicProcess();

    /*
     * @弃用
     */
    int musicStop();

    /*
     * @描述 获取音频总时间
     * @返回 正数返回总时间，否则失败
     */
    uint32_t getSumTimeSec();
    //int musicSetTimeSec(uint32_t t);

    /*
     * @描述 设置播放音量
     * @参数 v 音量，0到1之间
     */
    int musicSetVolum(double v);

signals:

    /*
     * @描述 向播放线程发送音频类以启动音频播放
     * @参数 mh 已解码的音频类
     */
    void play(musicHandle *mh);

    /*
     * @描述 向解码线程发送音频类以启动音频解码
     * @参数 mh 未解码的音频类
     */
    void process(musicHandle *mh);

    /*
     * @描述 以下三个信号在音频状态发生变化时发出
     */
    void statePlay();
    void stateDestroy();
    void statePause();

    void sendCurrentTime(int t);


public slots:

    /*
     * @描述 弃用
     */
    void musicProcessFinished();

    /*
     * @描述 修改当前播放时间，单位s
     * @参数 t 当前播放时间
     */
    void currentTimeChanged(uint32_t t);

    /*
     * @描述 设置当前播放时间
     * @参数 t 当前播放时间
     * @返回 0成功，否则失败
     */
    int musicSetTimeSec(int t);         //设置当前时间

    /*
     * @描述 对播放进行控制
     * @返回 0成功，否则失败
     */
    int musicStart();                   //开始播放
    int musicPause();
    int musicDestroy();
};

/*
 * @描述 音乐解码线程执行类
 */
class musicProcessThread : public QObject
{
    Q_OBJECT
public:
    musicProcessThread(QObject *parent = 0);
signals:

    /*
     * @描述 解码完成时发送
     */
    void processFinished();
public slots:

    /*
     * @描述 解码线程执行代码
     * @参数 mh 要解码的音频类
     */
    void doWork(musicHandle *mh);
};

/*
 * @描述 音乐播放线程执行类
 */
class musicPlayThread : public QObject
{
    Q_OBJECT
public:
    uint32_t startTimeSec;      //开始播放的时间，单位s
    uint32_t count;             //当前播放时间，单位ms，数据量1764 byte
    musicPlayThread(QObject *parent = 0);
signals:
    /*
     * @描述 count发出改变时发出，单位s
     */
    void currentTimeChanged(int t);    //count发生改变时发出
    //状态发生改变时发出

    /*
     * @描述 状态发生改变时发出
     */
    void statePlay();
    void stateDestroy();
    void statePause();
public slots:

    /*
     * @描述 音乐播放线程运行代码
     * @参数 mh 要播放的音乐类
     */
    void doWork(musicHandle *mh);

    /*
     * @描述 改变当前播放时间， 单位10ms
     */
    void changeCount(uint32_t c);
};





#endif // MUSICHANDLE_H
